﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AlgoTester
{
    class Trader
    {
        // Data Members
        protected string name;
        protected Date day;
        protected double cash;
        protected Stockmarket market;
        protected List<Certificate> stockHoldings;

        // Constructor
        public Trader(string name, Date day, double cash, Stockmarket market)
        {
            this.name = name;
            this.day = day;
            this.cash = cash;
            this.market = market;
            this.stockHoldings = new List<Certificate>();
        }

        // Main simulation driver
        public void nextDay(Date day)
        {
            this.day = day;
        }

        // Use for Trader to buy a stock
        // Returns whether the purchase was sucessful
        protected bool buyStock(Stock toBuy, int amount)
        {
            Certificate heldCertificate;
            String ticker = toBuy.getTicker();
            double totalPrice = (toBuy.getCurrentPrice() * amount);
            // Checks that Trader has enough cash for purchase
            if (totalPrice > cash)
                return false;
            // Adds to Certificate if a copy is already held, creates a
            // new one otherwise
            if (checkCertificateHolding(ticker))
            {
                heldCertificate = getCertificate(ticker);
                heldCertificate.gainQuantity(amount);
            }
            else
                stockHoldings.Add(new Certificate(amount, toBuy));
            // Pay for the Stock
            cash -= totalPrice;
            return true;
        }

        // Use for Trader to sell a stock
        // Returns whether the purchase was sucessful
        protected bool sellStock(Stock toSell, int amount)
        {
            Certificate heldCertificate;
            String stockTicker = toSell.getTicker();
            // Checks that Trader holds enough stock to sell
            if (checkCertificateHolding(stockTicker, amount))
            {
                // Subtract from Certificate, compensate trader with cash
                heldCertificate = getCertificate(stockTicker);
                heldCertificate.loseQuantity(amount);
                cash += heldCertificate.getPrice() * amount;
            }
            return false;
        }

        // Checks to see if a certificate of a Stock is held
        protected bool checkCertificateHolding(string stockTicker)
        {
            foreach (Certificate cert in stockHoldings)
                if (cert.getTicker().Equals(stockTicker))
                    return true;
            return false;
        }

        // Checks to see if a certificate of a Stock is held of at least a certain amount
        protected bool checkCertificateHolding(string stockTicker, int amount)
        {
            foreach (Certificate cert in stockHoldings)
                if (cert.getTicker().Equals(stockTicker))
                    if (cert.getQuantity() >= amount)
                        return true;
            return false;
        }

        // Use to retrieve the Stock associated with a ticker
        // Returns null if Stock not found
        protected Stock findStock(string ticker)
        {
            return market.findStock(ticker);
        }

        // Use to retrieve the Certificate associated with a ticker
        // Returns null if Certificate not found
        protected Certificate getCertificate(string ticker)
        {
            foreach (Certificate cert in stockHoldings)
                if (cert.getTicker().Equals(ticker))
                    return cert;
            return null;
        }

        protected String[] getTickersFromMarket()
        {
            return market.getTickers();
        }

    }
}
